import { effect, ReactiveEffectRunner,stop } from "@vue/reactivity";
import { Component,_decorator,Node } from "cc";
const { ccclass, property } = _decorator;



@ccclass('BaseComp')
export abstract class BaseComp extends Component{
    public viewName: string = '';//视图名,默认为类名
    // public viewNode: Node = null;//视图节点，会自动赋值


    protected effectRunners: ReactiveEffectRunner[] = [];
    public isInit = false;

    /**
     * 统一收集响应式的effect，用于在组件销毁或隐藏时停止
     * @param func
     * @returns 
     */
    protected addEffect(func: () => any) {
        if (func === undefined || func == null) {
            console.error("effect func is undefined or null!");
            return
        }
        let effectRunner = effect(func)
        this.effectRunners.push(effectRunner)
    }
    /**
     * 停止所有effect
     */
    protected stopEffect() {
        for (let i = 0; i < this.effectRunners.length; i++) {
            stop(this.effectRunners[i])
        }
    }

    public initControls(){
        if(this.isInit){
            return
        }
        let controls = this['controls'] as { [key: string]:{ componentPath: string ,classConstructure: new (...args: any[]) => any}};
        if(!controls){
            return
        }

        Object.keys(controls).forEach(key=>{
            let detail = controls[key];
            this[key] = this.getViewComponent(detail.classConstructure,detail.componentPath);
        })
    }



    /**
     * 根据路径获取子节点，格式：p1/p2/p3...;通用匹配符合：*表示任意层级，_表示一个层级
     */
    getViewComponent<T extends Component>(classConstructure: new (...args: any[]) => T, nodePath: string): T |Node| null {
        let paths = nodePath.split("/")
        if (paths.length == 0) {
            console.error("node path is null or empty!")
            return null
        }
        let node = this.node
        for (let index = 0; index < paths.length; index++) {
            const element = paths[index];
            let child = node.getChildByName(element)
            if (child == null) {
                console.error("路径不正确!未找到路径上的节点："+nodePath)
                return null
            }
            if (index == paths.length - 1) {
                if(classConstructure.name=="Node"){
                    return child as Node;
                }else{
                    let comp = child.getComponent(classConstructure)
                    if (comp == null) {
                        console.error("路径节点上未找到对应的组件，路径:"+nodePath+"  组件名："+classConstructure.name)
                        return null
                    }
                    return comp as T
                }
            } else {
                node = child
            }
        }
        return null
    }

        // =================init====================
    /**
    * 初始化方法，子类重写，整个生命周期只会一次
    */
    public init() { }


    // =================show====================
    /**
     * 显示组件前，启动所有effect，初始化操作等
     */
    beforeShow() {
        console.log("BasevView before show view:" + this.viewName);
    }
    /**
     * 用于激活组件
     */
    show() {
        console.log("BasevView show view:" + this.viewName);
        this.node.active = true;
    }
    /**
     * 视图显示后的操作
     */
    afterShow() {

    }


    // =================hide====================
    /**
 * 一般用于写退场动画？
 */
    beforeHide() {

    }
    /**
     * 用于隐藏组件，停止所有effect
     */
    hide() {
        console.log("BasevView hide view:" + this.viewName);
        this.stopEffect()
        this.node.active = false;
    }

    afterHide() {
        console.log("BasevView after hide view:" + this.viewName);
    }
}